import re
from spire.doc import *
import docx
from docx.shared import RGBColor



def read_doc(doc_path):
    # 创建一个 Document 类的对象并加载一个 Word 文档
    doc = Document()
    doc.LoadFromFile(doc_path)
    text = doc.GetText()
    text = text.replace('Evaluation Warning: The document was created with Spire.Doc for Python.\r\n','')
    return text



def delete_watermark(path):
    pydoc = docx.Document(path)
    for para in pydoc.paragraphs:
        if para.text == 'Evaluation Warning: The document was created with Spire.Doc for Python.':
            p = para._element
            p.getparent().remove(p)

    pydoc.save(path)


def mark_typos(doc_path,typos_info,save_path):
    # 创建一个新的列表用于存储去重合并后的结果
    merged_typos_info = []

    # 使用字典来记录每个"文本错误位置"及其对应的"文本错误内容"、"文本正确内容"和"错误原因"
    location_to_data = {}

    # 遍历typos_info列表
    for typo in typos_info:
        location = typo["文本错误位置"]
        error_content = typo["文本错误内容"]
        correct_content = typo["文本正确内容"]
        error_reason = typo["错误原因"]

        # 如果该位置已经存在于字典中，则添加错误内容、正确内容和错误原因到列表
        if location in location_to_data:
            location_to_data[location]["文本错误内容"].append(error_content)
            location_to_data[location]["文本正确内容"].append(correct_content)
            location_to_data[location]["错误原因"].append(error_reason)
        else:
            location_to_data[location] = {
                "文本错误位置": location,
                "文本错误内容": [error_content],
                "文本正确内容": [correct_content],
                "错误原因": [error_reason]
            }

    # 将字典转换为列表
    for data in location_to_data.values():
        merged_typos_info.append({
            "文本错误位置": data["文本错误位置"],
            "文本错误内容": data["文本错误内容"],
            "文本正确内容": data["文本正确内容"],
            "错误原因": data["错误原因"]
        })


    # 创建一个 Document 类的对象并加载一个 Word 文档
    doc = Document()
    doc.LoadFromFile(doc_path)
    for typos in merged_typos_info:

        # 因为/n匹配不了，所以进行分割，找到错误内容在第几行
        if '\n' in typos['文本错误位置']:
            a = typos['文本错误位置'].split('\n')
            for i in a:
                if typos['文本错误内容'] in i:
                    typos['文本错误位置'] = i

        sign_str = typos['文本错误位置']
        for i in range(len(typos['文本错误内容'])):
            sign_str = sign_str.replace(typos['文本错误内容'][i], f'<错别字占位符{i}>')

        # # 创建一个正则表达式来匹配以 # 开头的文本
        # regex = Regex(f"{typos['文本错误位置']}")
        doc.Replace(typos['文本错误位置'], sign_str, False, True)

        for i in range(len(typos['文本错误内容'])):
            text = doc.FindString(f'<错别字占位符{i}>', True, True)
            # 创建一个评论并设置评论的内容和作者
            comment = Comment(doc)
            comment.Body.AddParagraph().Text = typos['错误原因'][i]
            comment.Format.Author = "法伴"


            # 将找到的文本作为文本范围，并获取其所属的段落
            text_range = text.GetAsOneRange()
            paragraph = text_range.OwnerParagraph

            # 将评论添加到段落中
            paragraph.ChildObjects.Insert(paragraph.ChildObjects.IndexOf(text_range) + 1, comment)

            # 创建评论起始标记和结束标记，并将它们设置为创建的评论的起始标记和结束标记
            commentStart = CommentMark(doc, CommentMarkType.CommentStart)
            commentEnd = CommentMark(doc, CommentMarkType.CommentEnd)
            commentStart.CommentId = comment.Format.CommentId
            commentEnd.CommentId = comment.Format.CommentId

            # 在找到的文本之前和之后插入创建的评论起始和结束标记
            paragraph.ChildObjects.Insert(paragraph.ChildObjects.IndexOf(text_range), commentStart)
            paragraph.ChildObjects.Insert(paragraph.ChildObjects.IndexOf(text_range) + 1, commentEnd)

            doc.Replace(f'<错别字占位符{i}>', typos['文本错误内容'][i], False, True)


    # 保存文档
    doc.SaveToFile(save_path)
    doc.Close()
    delete_watermark(save_path)
    print('批注版已完成')

def replace_typos(doc_path,typos_info,save_path):
    # 创建一个 Document 类的对象并加载一个 Word 文档
    doc = Document()
    doc.LoadFromFile(doc_path)
    for index, typos in enumerate(typos_info):
        bad_text = typos['文本错误位置']
        # 判断前面一个错别字的错误位置和当前错别字的错误位置是否一样
        if index != 0:
            if bad_text == typos_info[index-1]['文本错误位置']:
                bad_text = good_str

        # 因为/n匹配不了，所以进行分割，找到错误内容在第几行
        if '\n' in bad_text:
            a = bad_text.split('\n')
            for i in a:
                if typos['文本错误内容'] in i:
                    bad_text = i

        # 遍历 节
        for i in range(0, 99):
            try:
                section = doc.Sections.get_Item(i)
            except:
                break
            # 遍历 段
            for j in range(0, 99):
                try:
                    para = section.Paragraphs.get_Item(j)
                except:
                    break
                # 在这一段里找 文本错误位置
                text_re = Regex(bad_text)
                text = para.Find(text_re)
                if text:
                    good_str = bad_text.replace(typos['文本错误内容'], typos['文本正确内容'])
                    para.Replace(bad_text, good_str, True, True)

    # 保存文档
    doc.SaveToFile(save_path)
    doc.Close()
    delete_watermark(save_path)
    print('正确版已完成')


if __name__ == "__main__":
    # typos_info = [
    #     {"文本错误位置": "树木从声", "文本错误内容": "从声", "文本正确内容": "丛生", "错误原因": "树木从声 的从声应该 丛生"},
    #     {"文本错误位置": "百草丰冒。\n秋风萧瑟，洪波涌起。", "文本错误内容": "冒", "文本正确内容": "茂", "错误原因": "百草丰冒 的冒应该是茂盛的 茂"},
    #     {"文本错误位置": "割以咏志", "文本错误内容": "割", "文本正确内容": "歌", "错误原因": "割以咏志 的割应该是歌唱的 歌"},
    # ]
    typos_info = [
        {"文本错误位置": "着是一格测试百度错屋文字的说明文档", "文本错误内容": "着是一格", "文本正确内容": "这是一份", "错误原因": "'着'应为'这'，'一格'应为'一份'，此处为形似字及语义理解错误"},
        {"文本错误位置": "着是一格测试百度错屋文字的说明文档", "文本错误内容": "错屋", "文本正确内容": "错误", "错误原因": "'错屋'应为'错误'，此处为形似字错误"},
        {"文本错误位置": "蠢天来了，输液绿了，鸟儿在欢唱，天气变煖了，事件万物在梦雅", "文本错误内容": "蠢天", "文本正确内容": "春天", "错误原因": "'蠢天'应为'春天'，此处为形似字及语义理解错误"},
        {"文本错误位置": "蠢天来了，输液绿了，鸟儿在欢唱，天气变煖了，事件万物在梦雅", "文本错误内容": "煖了", "文本正确内容": "暖了", "错误原因": "'煖'应为'暖'，此处为形似字错误"},
        {"文本错误位置": "蠢天来了，输液绿了，鸟儿在欢唱，天气变煖了，事件万物在梦雅", "文本错误内容": "事件", "文本正确内容": "一切", "错误原因": "'事件'应为'一切'，此处为形似字及语义理解错误"},
        {"文本错误位置": "蠢天来了，输液绿了，鸟儿在欢唱，天气变煖了，事件万物在梦雅", "文本错误内容": "梦雅", "文本正确内容": "萌芽", "错误原因": "'梦雅'应为'萌芽'，此处为形似字及语义理解错误"},
        {"文本错误位置": "具体的时间详情", "文本错误内容": "时间", "文本正确内容": "事件", "错误原因": "'时间'应为'事件'，此处为形似字及语义理解错误"}
        ]

    # 读取用户上传的docx
    doc_path = 'typos_doc/百度测试错别字.docx'

    # 导出的批注版和正确版文件
    mark_doc_path = 'result/批注.docx'
    right_doc_path = 'result/正确.docx'

    # 进行批注,导出批注版
    mark_typos(doc_path, typos_info, mark_doc_path)

    # 替换错别字，导出正确版
    replace_typos(doc_path, typos_info, right_doc_path)
